home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1994 August / August CD.bin / Shareware / Programming / SpriteWorld / Sources / BlitPixie.c next >
Text File  |  1994-04-25  |  28KB  |  935 lines

  1. ///--------------------------------------------------------------------------------------
  2. //    BlitPixie.c
  3. //
  4. //    Created:    Thursday, September 24, 1992 at 11:48 PM
  5. //    By:        Tony Myles
  6. //
  7. //    Ideas and code snippets contributed by:
  8. //        Ben Sharpe, Brigham Stevens, Sean Callahan, and Joe Britt
  9. //
  10. //    Copyright: © 1991-94 Tony Myles, All rights reserved worldwide.
  11. ///--------------------------------------------------------------------------------------
  12.  
  13.  
  14. #ifndef __SWCOMMON__
  15. #include "SWCommonHeaders.h"
  16. #endif
  17.  
  18. #ifndef __TOOLUTILS__
  19. #include <ToolUtils.h>
  20. #endif
  21.  
  22. #ifndef __OSUTILS__
  23. #include <OSUtils.h>
  24. #endif
  25.  
  26. #ifndef __QUICKDRAW__
  27. #include <Quickdraw.h>
  28. #endif
  29.  
  30. #ifndef __QDOFFSCREEN__
  31. #include <QDOffscreen.h>
  32. #endif
  33.  
  34. #ifndef __FRAME__
  35. #include "Frame.h"
  36. #endif
  37.  
  38. #ifndef __BLITPIXIE__
  39. #include "BlitPixie.h"
  40. #endif
  41.  
  42. #ifndef __SPRITECOMPILER__
  43. #include "SpriteCompiler.h"
  44. #endif
  45.  
  46. #include "DebugUtils.h"
  47.  
  48.  
  49. ///--------------------------------------------------------------------------------------
  50. //        BlitPixieSpriteDrawProc
  51. ///--------------------------------------------------------------------------------------
  52.  
  53. SW_FUNC void BlitPixieSpriteDrawProc(
  54.     FramePtr srcFrameP,
  55.     FramePtr dstFrameP,
  56.     Rect *srcRect,
  57.     Rect *dstRect)
  58. {
  59.     Rect srcBlitRect = *srcRect;
  60.     Rect dstBlitRect = *dstRect;
  61.  
  62.         // clip off the top so we dont write into random memory
  63.     if (dstBlitRect.top < dstFrameP->frameRect.top)
  64.     {
  65.         srcBlitRect.top += dstFrameP->frameRect.top - dstBlitRect.top;
  66.         dstBlitRect.top = dstFrameP->frameRect.top;
  67.         if (dstBlitRect.top >= dstBlitRect.bottom) return;
  68.     }
  69.         // clip off the bottom
  70.     else if (dstBlitRect.bottom > dstFrameP->frameRect.bottom)
  71.     {
  72.         dstBlitRect.bottom = dstFrameP->frameRect.bottom;
  73.         if (dstBlitRect.bottom <= dstBlitRect.top) return;
  74.     }
  75.  
  76.         // clip off the left
  77.     if (dstBlitRect.left < dstFrameP->frameRect.left)
  78.     {
  79.         srcBlitRect.left += dstFrameP->frameRect.left - dstBlitRect.left;
  80.         dstBlitRect.left = dstFrameP->frameRect.left;
  81.         if (dstBlitRect.left >= dstBlitRect.right) return;
  82.     }
  83.         // clip off the right
  84.     else if (dstBlitRect.right > dstFrameP->frameRect.right)
  85.     {
  86.         dstBlitRect.right = dstFrameP->frameRect.right;
  87.         if (dstBlitRect.right <= dstBlitRect.left) return;
  88.     }
  89.  
  90.     {
  91.         unsigned long numBytesPerRow;
  92.  
  93.             // calculate the number of bytes in a row
  94.         numBytesPerRow = (dstBlitRect.right - dstBlitRect.left);
  95.  
  96.         BlitPixie(
  97.                 // calculate the address of the first byte of the source
  98.             (PixelChunkPtr)(srcFrameP->frameBaseAddr + 
  99.                 (srcFrameP->scanLinePtrArray[srcBlitRect.top]) + srcBlitRect.left),
  100.  
  101.                 // calculate the address of the first byte of the destination
  102.             (PixelChunkPtr)(dstFrameP->frameBaseAddr + 
  103.                 (dstFrameP->scanLinePtrArray[dstBlitRect.top]) + dstBlitRect.left),
  104.  
  105.                 // calculate the number of rows to blit
  106.             dstBlitRect.bottom - dstBlitRect.top,
  107.  
  108.                 // number of bytes in a row (duh!)
  109.             numBytesPerRow,
  110.  
  111.                 // calculate offset from end of one row to beginning of next row
  112.             srcFrameP->frameRowBytes - numBytesPerRow,
  113.             dstFrameP->frameRowBytes - numBytesPerRow);
  114.     }
  115. }
  116.  
  117.  
  118. ///--------------------------------------------------------------------------------------
  119. //        BlitPixieWorldDrawProc
  120. ///--------------------------------------------------------------------------------------
  121.  
  122. SW_FUNC void BlitPixieWorldDrawProc(
  123.     FramePtr srcFrameP,
  124.     FramePtr dstFrameP,
  125.     Rect *blitRect)
  126. {
  127.     Rect dstBlitRect = *blitRect;
  128.     Rect srcBlitRect = *blitRect;
  129.  
  130.         // clip off the top so we dont write into random memory
  131.     if (dstBlitRect.top <  dstFrameP->frameRect.top)
  132.     {
  133.         srcBlitRect.top += dstFrameP->frameRect.top - dstBlitRect.top;
  134.         dstBlitRect.top =  dstFrameP->frameRect.top;
  135.         if (dstBlitRect.top >= dstBlitRect.bottom) return;    
  136.     }
  137.         // clip off the bottom
  138.     else if (dstBlitRect.bottom >  dstFrameP->frameRect.bottom)
  139.     {
  140.         dstBlitRect.bottom =  dstFrameP->frameRect.bottom;
  141.         if (dstBlitRect.bottom <= dstBlitRect.top) return;
  142.     }
  143.  
  144.         // clip off the left
  145.     if (dstBlitRect.left <  dstFrameP->frameRect.left)
  146.     {
  147.         srcBlitRect.left += dstFrameP->frameRect.left - dstBlitRect.left;
  148.         dstBlitRect.left =  dstFrameP->frameRect.left;
  149.         if (dstBlitRect.left >= dstBlitRect.right) return;
  150.     }
  151.         // clip off the right
  152.     else if (dstBlitRect.right >  dstFrameP->frameRect.right)
  153.     {
  154.         dstBlitRect.right =  dstFrameP->frameRect.right;
  155.         if (dstBlitRect.right <= dstBlitRect.left) return;
  156.     }
  157.  
  158.     {
  159.         unsigned long numBytesPerRow;
  160.  
  161.             // calculate the number of bytes in a row
  162.         numBytesPerRow = (dstBlitRect.right - dstBlitRect.left);
  163.  
  164.         BlitPixieChunks(
  165.                 // calculate the address of the first byte of the source
  166.             (PixelChunkPtr)(srcFrameP->frameBaseAddr + 
  167.                 (srcFrameP->scanLinePtrArray[srcBlitRect.top]) + srcBlitRect.left),
  168.  
  169.                 // calculate the address of the first byte of the destination
  170.                 // compensate for the offset of the destination pixmap
  171.                 // since we may be drawing to the screen
  172.             (PixelChunkPtr)(dstFrameP->frameBaseAddr + 
  173.                 (dstFrameP->scanLinePtrArray[(dstBlitRect.top + -dstFrameP->framePix.pixMapP->bounds.top)])
  174.                  + (dstBlitRect.left + -dstFrameP->framePix.pixMapP->bounds.left)),
  175.  
  176.                 // calculate the number of rows to blit
  177.             dstBlitRect.bottom - dstBlitRect.top,
  178.  
  179.                 // number of chunks per row
  180.             BytesToChunks(numBytesPerRow),
  181.  
  182.                 // calculate offset from end of one row to beginning of next row
  183.             srcFrameP->frameRowBytes - numBytesPerRow,
  184.             dstFrameP->frameRowBytes - numBytesPerRow);
  185.     }
  186. }
  187.  
  188.  
  189. ///--------------------------------------------------------------------------------------
  190. //        BlitPixieMaskDrawProc
  191. ///--------------------------------------------------------------------------------------
  192.  
  193. SW_FUNC void BlitPixieMaskDrawProc(
  194.     FramePtr srcFrameP,
  195.     FramePtr dstFrameP,
  196.     Rect *srcRect,
  197.     Rect *dstRect)
  198. {
  199.     Rect dstBlitRect = *dstRect;
  200.     Rect srcBlitRect = *srcRect;
  201.  
  202.         // clip off the top so we dont write into random memory
  203.     if (dstBlitRect.top <  dstFrameP->frameRect.top)
  204.     {
  205.         srcBlitRect.top += dstFrameP->frameRect.top - dstBlitRect.top;
  206.         dstBlitRect.top =  dstFrameP->frameRect.top;
  207.         if (dstBlitRect.top >= dstBlitRect.bottom) return;    
  208.     }
  209.         // clip off the bottom
  210.     else if (dstBlitRect.bottom >  dstFrameP->frameRect.bottom)
  211.     {
  212.         dstBlitRect.bottom =  dstFrameP->frameRect.bottom;
  213.         if (dstBlitRect.bottom <= dstBlitRect.top) return;
  214.     }
  215.  
  216.         // clip off the left
  217.     if (dstBlitRect.left <  dstFrameP->frameRect.left)
  218.     {
  219.         srcBlitRect.left += dstFrameP->frameRect.left - dstBlitRect.left;
  220.         dstBlitRect.left =  dstFrameP->frameRect.left;
  221.         if (dstBlitRect.left >= dstBlitRect.right) return;
  222.     }
  223.         // clip off the right
  224.     else if (dstBlitRect.right >  dstFrameP->frameRect.right)
  225.     {
  226.         dstBlitRect.right =  dstFrameP->frameRect.right;
  227.         if (dstBlitRect.right <= dstBlitRect.left) return;
  228.     }
  229.  
  230.     {
  231.         unsigned long numBytesPerRow;
  232.         unsigned long srcBaseOffset;
  233.  
  234.             // calculate the offset to the first byte of the source
  235.         srcBaseOffset = srcFrameP->scanLinePtrArray[srcBlitRect.top] + srcBlitRect.left;
  236.  
  237.             // calculate the number of bytes in a row
  238.         numBytesPerRow = (dstBlitRect.right - dstBlitRect.left);
  239.  
  240.         BlitPixieMask(
  241.                 // calculate the address of the first byte of the source
  242.             (PixelPtr)(srcFrameP->frameBaseAddr + srcBaseOffset),
  243.  
  244.                 // calculate the address of the first byte of the destination
  245.             (PixelPtr)(dstFrameP->frameBaseAddr + 
  246.                 (dstFrameP->scanLinePtrArray[dstBlitRect.top]) + dstBlitRect.left),
  247.  
  248.                 // calculate the address of the first byte of the mask
  249.             (PixelPtr)(srcFrameP->maskBaseAddr + srcBaseOffset),
  250.  
  251.                 // calculate the number of rows to blit
  252.             dstBlitRect.bottom - dstBlitRect.top,
  253.  
  254.                 // number of bytes in a row (duh!)
  255.             numBytesPerRow,
  256.  
  257.                 // calculate offset from end of one row to beginning of next row
  258.             srcFrameP->frameRowBytes - numBytesPerRow,
  259.             dstFrameP->frameRowBytes - numBytesPerRow);
  260.     }
  261. }
  262.  
  263.  
  264. ///--------------------------------------------------------------------------------------
  265. //        CompiledSpriteDrawProc
  266. ///--------------------------------------------------------------------------------------
  267.  
  268. SW_FUNC void CompiledSpriteDrawProc(
  269.     FramePtr srcFrameP,
  270.     FramePtr dstFrameP,
  271.     Rect *srcRect,
  272.     Rect *dstRect)
  273. {
  274.     Rect dstBlitRect = *dstRect;
  275.     Rect srcBlitRect = *srcRect;
  276.     Boolean useCustomBlitter = true;    // assume we will be able to use the custom blitter
  277.  
  278.     // we first check to see if any clipping will be necessary, and at the same time
  279.     // we determine whether or not we can use the custom compiled blitter. we must
  280.     // do this since the custom blitter cannot handle clipping.
  281.  
  282.         // clip off the top so we dont write into random memory
  283.     if (dstBlitRect.top <  dstFrameP->frameRect.top)
  284.     {
  285.         srcBlitRect.top += dstFrameP->frameRect.top - dstBlitRect.top;
  286.         dstBlitRect.top =  dstFrameP->frameRect.top;
  287.         if (dstBlitRect.top >= dstBlitRect.bottom) return;
  288.         useCustomBlitter = false;    
  289.     }
  290.         // clip off the bottom
  291.     else if (dstBlitRect.bottom >  dstFrameP->frameRect.bottom)
  292.     {
  293.         dstBlitRect.bottom =  dstFrameP->frameRect.bottom;
  294.         if (dstBlitRect.bottom <= dstBlitRect.top) return;
  295.         useCustomBlitter = false;    
  296.     }
  297.  
  298.         // clip off the left
  299.     if (dstBlitRect.left <  dstFrameP->frameRect.left)
  300.     {
  301.         srcBlitRect.left += dstFrameP->frameRect.left - dstBlitRect.left;
  302.         dstBlitRect.left =  dstFrameP->frameRect.left;
  303.         if (dstBlitRect.left >= dstBlitRect.right) return;
  304.         useCustomBlitter = false;    
  305.     }
  306.         // clip off the right
  307.     else if (dstBlitRect.right >  dstFrameP->frameRect.right)
  308.     {
  309.         dstBlitRect.right =  dstFrameP->frameRect.right;
  310.         if (dstBlitRect.right <= dstBlitRect.left) return;
  311.         useCustomBlitter = false;    
  312.     }
  313.  
  314.     // if we didn't have to clip the sprite, we can call the custom compiled blitter
  315.     // hopefully this will be the most common case (ie. the sprites will be entirely
  316.     // on the screen more often than not)
  317.  
  318.     if (useCustomBlitter)
  319.     {
  320.         (*srcFrameP->frameBlitterP)(
  321.             srcFrameP->frameRowBytes,
  322.             dstFrameP->frameRowBytes,
  323.             srcFrameP->frameBaseAddr,
  324.             dstFrameP->frameBaseAddr +
  325.                 dstFrameP->scanLinePtrArray[dstRect->top] + dstRect->left);
  326.     }
  327.     else
  328.     {
  329.         unsigned long numBytesPerRow;
  330.         unsigned long srcBaseOffset;
  331.  
  332.             // calculate the offset to the first byte of the source
  333.         srcBaseOffset = srcFrameP->scanLinePtrArray[srcBlitRect.top] + srcBlitRect.left;
  334.  
  335.             // calculate the number of bytes in a row
  336.         numBytesPerRow = (dstBlitRect.right - dstBlitRect.left);
  337.  
  338.         BlitPixieMask(
  339.                 // calculate the address of the first byte of the source
  340.             (PixelPtr)(srcFrameP->frameBaseAddr + srcBaseOffset),
  341.  
  342.                 // calculate the address of the first byte of the destination
  343.             (PixelPtr)(dstFrameP->frameBaseAddr + 
  344.                 (dstFrameP->scanLinePtrArray[dstBlitRect.top]) + dstBlitRect.left),
  345.  
  346.                 // calculate the address of the first byte of the mask
  347.             (PixelPtr)(srcFrameP->maskBaseAddr + srcBaseOffset),
  348.  
  349.                 // calculate the number of rows to blit
  350.             dstBlitRect.bottom - dstBlitRect.top,
  351.  
  352.                 // number of bytes in a row (duh!)
  353.             numBytesPerRow,
  354.  
  355.                 // calculate offset from end of one row to beginning of next row
  356.             srcFrameP->frameRowBytes - numBytesPerRow,
  357.             dstFrameP->frameRowBytes - numBytesPerRow);
  358.     }
  359. }
  360.  
  361.  
  362. ///--------------------------------------------------------------------------------------
  363. //        FastCompiledSpriteDrawProc
  364. ///--------------------------------------------------------------------------------------
  365.  
  366. SW_FUNC void FastCompiledSpriteDrawProc(
  367.     FramePtr srcFrameP,
  368.     FramePtr dstFrameP,
  369.     Rect *srcRect,
  370.     Rect *dstRect)
  371. {
  372. #if MPW
  373. #pragma unused(srcRect)
  374. #endif
  375.  
  376.         // this draw proc assumes no clipping of the sprite will be necessary.
  377.         // in other words the sprite must be *entirely* on the screen.
  378.         // if the sprite is partially off the edge of the screen,
  379.         //    this will *CRASH* big time
  380.  
  381.     (*srcFrameP->frameBlitterP)(
  382.         srcFrameP->frameRowBytes,
  383.         dstFrameP->frameRowBytes,
  384.         srcFrameP->frameBaseAddr,
  385.         dstFrameP->frameBaseAddr + dstFrameP->scanLinePtrArray[dstRect->top] + dstRect->left);
  386. }
  387.  
  388.  
  389. #if SW_USE_C
  390.  
  391. ///--------------------------------------------------------------------------------------
  392. //        BlitPixie
  393. ///--------------------------------------------------------------------------------------
  394.  
  395. void BlitPixie(
  396.     register PixelChunkPtr srcPixelP,
  397.     register PixelChunkPtr dstPixelP,
  398.     register unsigned long rowsToCopy,
  399.     register unsigned long numBytesPerRow,
  400.     register unsigned long srcRowStride,
  401.     register unsigned long dstRowStride)
  402. {
  403.     register long loopsPerRow;
  404.     register long extraPixelChunks;
  405.     register long pixelChunksPerRow;
  406.  
  407.     pixelChunksPerRow = BytesToChunks(numBytesPerRow); 
  408.     extraPixelChunks = pixelChunksPerRow & 0xF;        
  409.     pixelChunksPerRow >>= 4;
  410.  
  411.     while (rowsToCopy--)
  412.     {
  413.             // we reuse pixelChunksPerRow to restore loopsPerRow
  414.         loopsPerRow = pixelChunksPerRow;
  415.  
  416.             // this maniacal, though extremely convenient bit of C code
  417.             // is a Duff-style unrolled loop, an invention of Tom Duff at Bellcore.
  418.             // I've heard it breaks some compilers, but it does have
  419.             //    Dennis Ritchie's blessing as valid C code.
  420.         switch (extraPixelChunks)
  421.         {
  422.             do
  423.             {
  424.                             BlitPixelChunk(srcPixelP, dstPixelP);
  425.                 case 15:    BlitPixelChunk(srcPixelP, dstPixelP);
  426.                 case 14:    BlitPixelChunk(srcPixelP, dstPixelP);
  427.                 case 13:    BlitPixelChunk(srcPixelP, dstPixelP);
  428.                 case 12:    BlitPixelChunk(srcPixelP, dstPixelP);
  429.                 case 11:    BlitPixelChunk(srcPixelP, dstPixelP);
  430.                 case 10:    BlitPixelChunk(srcPixelP, dstPixelP);
  431.                 case 9:    BlitPixelChunk(srcPixelP, dstPixelP);
  432.                 case 8:    BlitPixelChunk(srcPixelP, dstPixelP);
  433.                 case 7:    BlitPixelChunk(srcPixelP, dstPixelP);
  434.                 case 6:    BlitPixelChunk(srcPixelP, dstPixelP);
  435.                 case 5:    BlitPixelChunk(srcPixelP, dstPixelP);
  436.                 case 4:    BlitPixelChunk(srcPixelP, dstPixelP);
  437.                 case 3:    BlitPixelChunk(srcPixelP, dstPixelP);
  438.                 case 2:    BlitPixelChunk(srcPixelP, dstPixelP);
  439.                 case 1:    BlitPixelChunk(srcPixelP, dstPixelP);
  440.                 case 0: ;
  441.             } while (loopsPerRow--);
  442.         }
  443.  
  444.             // bump to the next row
  445.         srcPixelP = (PixelChunkPtr)(((char*)srcPixelP) + srcRowStride);
  446.         dstPixelP = (PixelChunkPtr)(((char*)dstPixelP) + dstRowStride);
  447.     }
  448. }
  449.  
  450.  
  451. ///--------------------------------------------------------------------------------------
  452. //        BlitPixieChunks
  453. ///--------------------------------------------------------------------------------------
  454.  
  455. void BlitPixieChunks(
  456.     register PixelChunkPtr srcPixelP,
  457.     register PixelChunkPtr dstPixelP,
  458.     register unsigned long rowsToCopy,
  459.     register unsigned long pixelChunksPerRow,
  460.     register unsigned long srcRowStride,
  461.     register unsigned long dstRowStride)
  462. {
  463.     register long loopsPerRow;
  464.     register long extraPixelChunks;
  465.  
  466.     extraPixelChunks = pixelChunksPerRow & 0xF;        
  467.     pixelChunksPerRow >>= 4;
  468.  
  469.     while (rowsToCopy--)
  470.     {
  471.             // we reuse pixelChunksPerRow to restore loopsPerRow
  472.         loopsPerRow = pixelChunksPerRow;
  473.  
  474.             // this maniacal, though extremely convenient bit of C code
  475.             // is a Duff-style unrolled loop, an invention of Tom Duff at Bellcore.
  476.             // I've heard it breaks some compilers, but it does have
  477.             //    Dennis Ritchie's blessing as valid C code.
  478.         switch (extraPixelChunks)
  479.         {
  480.             do
  481.             {
  482.                             BlitPixelChunk(srcPixelP, dstPixelP);
  483.                 case 15:    BlitPixelChunk(srcPixelP, dstPixelP);
  484.                 case 14:    BlitPixelChunk(srcPixelP, dstPixelP);
  485.                 case 13:    BlitPixelChunk(srcPixelP, dstPixelP);
  486.                 case 12:    BlitPixelChunk(srcPixelP, dstPixelP);
  487.                 case 11:    BlitPixelChunk(srcPixelP, dstPixelP);
  488.                 case 10:    BlitPixelChunk(srcPixelP, dstPixelP);
  489.                 case 9:    BlitPixelChunk(srcPixelP, dstPixelP);
  490.                 case 8:    BlitPixelChunk(srcPixelP, dstPixelP);
  491.                 case 7:    BlitPixelChunk(srcPixelP, dstPixelP);
  492.                 case 6:    BlitPixelChunk(srcPixelP, dstPixelP);
  493.                 case 5:    BlitPixelChunk(srcPixelP, dstPixelP);
  494.                 case 4:    BlitPixelChunk(srcPixelP, dstPixelP);
  495.                 case 3:    BlitPixelChunk(srcPixelP, dstPixelP);
  496.                 case 2:    BlitPixelChunk(srcPixelP, dstPixelP);
  497.                 case 1:    BlitPixelChunk(srcPixelP, dstPixelP);
  498.                 case 0: ;
  499.             } while (loopsPerRow--);
  500.         }
  501.  
  502.             // bump to the next row
  503.         srcPixelP = (PixelChunkPtr)(((char*)srcPixelP) + srcRowStride);
  504.         dstPixelP = (PixelChunkPtr)(((char*)dstPixelP) + dstRowStride);
  505.     }
  506. }
  507.  
  508.  
  509. ///--------------------------------------------------------------------------------------
  510. //        BlitPixieMask
  511. ///--------------------------------------------------------------------------------------
  512.  
  513. void BlitPixieMask(
  514.     register PixelPtr srcPixelP,
  515.     register PixelPtr dstPixelP,
  516.     register PixelPtr maskPixelP,
  517.     register unsigned long rowsToCopy,
  518.     register unsigned long longWordsPerRow,        // this is really numBytesPerRow
  519.     register unsigned long srcRowStride,
  520.     register unsigned long dstRowStride)
  521. {
  522.     register long loopsPerRow;
  523.     register long extraPixelLongs;
  524.  
  525.     longWordsPerRow >>= 2;
  526.     extraPixelLongs = longWordsPerRow & 0xF;
  527.     longWordsPerRow >>= 4;
  528.  
  529.     while (rowsToCopy--)
  530.     {
  531.         loopsPerRow = longWordsPerRow;
  532.  
  533.             // this maniacal, though extremely convenient bit of C code
  534.             // is a Duff-style unrolled loop, an invention of Tom Duff at Bellcore.
  535.             // I've heard it breaks some compilers, but it does have
  536.             //    Dennis Ritchie's blessing as valid C code.
  537.         switch (extraPixelLongs)
  538.         {
  539.             do
  540.             {
  541.                             BlitPixelLongMask(srcPixelP, dstPixelP, maskPixelP);
  542.                 case 15:    BlitPixelLongMask(srcPixelP, dstPixelP, maskPixelP);
  543.                 case 14:    BlitPixelLongMask(srcPixelP, dstPixelP, maskPixelP);
  544.                 case 13:    BlitPixelLongMask(srcPixelP, dstPixelP, maskPixelP);
  545.                 case 12:    BlitPixelLongMask(srcPixelP, dstPixelP, maskPixelP);
  546.                 case 11:    BlitPixelLongMask(srcPixelP, dstPixelP, maskPixelP);
  547.                 case 10:    BlitPixelLongMask(srcPixelP, dstPixelP, maskPixelP);
  548.                 case 9:    BlitPixelLongMask(srcPixelP, dstPixelP, maskPixelP);
  549.                 case 8:    BlitPixelLongMask(srcPixelP, dstPixelP, maskPixelP);
  550.                 case 7:    BlitPixelLongMask(srcPixelP, dstPixelP, maskPixelP);
  551.                 case 6:    BlitPixelLongMask(srcPixelP, dstPixelP, maskPixelP);
  552.                 case 5:    BlitPixelLongMask(srcPixelP, dstPixelP, maskPixelP);
  553.                 case 4:    BlitPixelLongMask(srcPixelP, dstPixelP, maskPixelP);
  554.                 case 3:    BlitPixelLongMask(srcPixelP, dstPixelP, maskPixelP);
  555.                 case 2:    BlitPixelLongMask(srcPixelP, dstPixelP, maskPixelP);
  556.                 case 1:    BlitPixelLongMask(srcPixelP, dstPixelP, maskPixelP);
  557.                 case 0: ;
  558.             } while (loopsPerRow--);
  559.         }
  560.  
  561.             // bump to the next row
  562.         srcPixelP = (PixelPtr)(((unsigned char*)srcPixelP) + srcRowStride);
  563.         maskPixelP = (PixelPtr)(((unsigned char*)maskPixelP) + srcRowStride);
  564.         dstPixelP = (PixelPtr)(((unsigned char*)dstPixelP) + dstRowStride);
  565.     }
  566. }
  567.  
  568.  
  569. #else /* SW_USE_C */
  570.  
  571.  
  572. ///--------------------------------------------------------------------------------------
  573. //        BlitPixie
  574. ///--------------------------------------------------------------------------------------
  575.  
  576. SW_ASM_FUNC void BlitPixie(
  577.     register PixelPtr srcPixelP,
  578.     register PixelPtr dstPixelP,
  579.     register unsigned long rowsToCopy,
  580.     register unsigned long numBytesPerRow,
  581.     register unsigned long srcRowStride,
  582.     register unsigned long dstRowStride)
  583. {
  584.     register unsigned long loopsPerRow;
  585.  
  586.         SW_ASM_BEGIN
  587.  
  588. #if __MWERKS__
  589.         movem.l            loopsPerRow/srcPixelP/dstPixelP/rowsToCopy/numBytesPerRow/srcRowStride/dstRowStride, -(sp)
  590.  
  591.             // move the parameters into registers
  592.         movea.l            28(sp), srcPixelP
  593.         movea.l            32(sp), dstPixelP
  594.         move.l            36(sp), rowsToCopy
  595.         move.l            40(sp), numBytesPerRow
  596.         move.l            44(sp), srcRowStride
  597.         move.l            48(sp), dstRowStride
  598. #endif
  599.  
  600.             // longWordsPerRow = numBytesPerRow >> 2;
  601.         move.l    numBytesPerRow, d0
  602.         lsr.l        #2, d0
  603.  
  604.             // numBytesPerRow -= longWordsPerRow << 2;
  605.         move.l    d0, d1
  606.         lsl.l        #2, d1
  607.         sub.l        d1, numBytesPerRow
  608.  
  609.             // loopsPerRow = longWordsPerRow >> 4;
  610.         move.l    d0, loopsPerRow
  611.         lsr.l        #4, loopsPerRow
  612.  
  613.         moveq        #0xF, d1
  614.         and.l        d1, d0
  615.         add.l        d0, d0            // multiply longWordsPerRow by 2 (size of move.l (srcPixelP)+,(dstPixelP)+)
  616.         lea         @loopEnd, a0    // get address of the end of the loop
  617.         suba.l    d0, a0            // calculate where to jmp in the loop
  618.  
  619.     @forEachRow:
  620.         move.l    loopsPerRow, d0
  621.         jmp        (a0)
  622.     @loopBase:
  623.         move.l    (srcPixelP)+, (dstPixelP)+    // 16
  624.         move.l    (srcPixelP)+, (dstPixelP)+    // 15
  625.         move.l    (srcPixelP)+, (dstPixelP)+    // 14
  626.         move.l    (srcPixelP)+, (dstPixelP)+    // 13
  627.         move.l    (srcPixelP)+, (dstPixelP)+    // 12
  628.         move.l    (srcPixelP)+, (dstPixelP)+    // 11 
  629.         move.l    (srcPixelP)+, (dstPixelP)+    // 10
  630.         move.l    (srcPixelP)+, (dstPixelP)+    //  9
  631.         move.l    (srcPixelP)+, (dstPixelP)+    //  8
  632.         move.l    (srcPixelP)+, (dstPixelP)+    //  7
  633.         move.l    (srcPixelP)+, (dstPixelP)+    //  6
  634.         move.l    (srcPixelP)+, (dstPixelP)+    //  5
  635.         move.l    (srcPixelP)+, (dstPixelP)+    //  4
  636.         move.l    (srcPixelP)+, (dstPixelP)+    //  3
  637.         move.l    (srcPixelP)+, (dstPixelP)+    //  2
  638.         move.l    (srcPixelP)+, (dstPixelP)+    //  1
  639.     @loopEnd:
  640.         subq.l    #1,d0
  641.         bpl        @loopBase
  642.  
  643.         // now do any leftover bits
  644.         move.l    numBytesPerRow, d0
  645.         beq        @nextRow
  646.         subq.l    #2, d0
  647.         bmi        @moveByte
  648.         move.w    (srcPixelP)+, (dstPixelP)+
  649.         tst        d0
  650.         beq        @nextRow
  651.     @moveByte:    
  652.         move.b    (srcPixelP)+, (dstPixelP)+
  653.  
  654.     @nextRow:
  655.         adda.l    srcRowStride, srcPixelP
  656.         adda.l    dstRowStride, dstPixelP
  657.         subq.l    #1, rowsToCopy
  658.         bne        @forEachRow
  659.  
  660. #if __MWERKS__
  661.         movem.l            (sp)+,    loopsPerRow/srcPixelP/dstPixelP/rowsToCopy/numBytesPerRow/srcRowStride/dstRowStride
  662. #endif
  663.  
  664.         SW_ASM_END
  665. }
  666.  
  667.  
  668. ///--------------------------------------------------------------------------------------
  669. //        BlitPixieChunks
  670. ///--------------------------------------------------------------------------------------
  671.  
  672. SW_ASM_FUNC void BlitPixieChunks(
  673.     register PixelChunkPtr srcPixelP,
  674.     register PixelChunkPtr dstPixelP,
  675.     register unsigned long rowsToCopy,
  676.     register unsigned long pixelChunksPerRow,
  677.     register unsigned long srcRowStride,
  678.     register unsigned long dstRowStride)
  679. {
  680.     register unsigned long loopsPerRow;
  681.  
  682.             SW_ASM_BEGIN
  683.  
  684. #if __MWERKS__
  685.             movem.l            loopsPerRow/rowsToCopy/pixelChunksPerRow/srcRowStride/dstRowStride/srcPixelP/dstPixelP, -(sp)
  686.  
  687.                 // move the parameters into registers
  688.             movea.l            32(sp), srcPixelP
  689.             movea.l            36(sp), dstPixelP
  690.             move.l            40(sp), rowsToCopy
  691.             move.l            44(sp), pixelChunksPerRow
  692.             move.l            48(sp), srcRowStride
  693.             move.l            52(sp), dstRowStride
  694. #endif
  695.                 // calculate number of loops per row of pixels
  696.                 // loopsPerRow = pixelChunksPerRow >> 4;
  697.             move.l            pixelChunksPerRow, loopsPerRow
  698.             lsr.l                #4, loopsPerRow
  699.  
  700.                 // calculate which move.l to jump to
  701.             moveq                #0xF, d0
  702.             and.l                d0, pixelChunksPerRow
  703.             add.l                pixelChunksPerRow, pixelChunksPerRow
  704.             lea                 @preLoopEnd, a0
  705.             suba.l            pixelChunksPerRow, a0
  706.  
  707.     @forEachRow:
  708.             jmp                (a0)
  709.             move.l            (srcPixelP)+, (dstPixelP)+
  710.             move.l            (srcPixelP)+, (dstPixelP)+
  711.             move.l            (srcPixelP)+, (dstPixelP)+
  712.             move.l            (srcPixelP)+, (dstPixelP)+
  713.             move.l            (srcPixelP)+, (dstPixelP)+
  714.             move.l            (srcPixelP)+, (dstPixelP)+
  715.             move.l            (srcPixelP)+, (dstPixelP)+
  716.             move.l            (srcPixelP)+, (dstPixelP)+
  717.             move.l            (srcPixelP)+, (dstPixelP)+
  718.             move.l            (srcPixelP)+, (dstPixelP)+
  719.             move.l            (srcPixelP)+, (dstPixelP)+
  720.             move.l            (srcPixelP)+, (dstPixelP)+
  721.             move.l            (srcPixelP)+, (dstPixelP)+
  722.             move.l            (srcPixelP)+, (dstPixelP)+
  723.             move.l            (srcPixelP)+, (dstPixelP)+
  724.     @preLoopEnd:
  725.  
  726.             move.l            loopsPerRow, d0
  727.             beq                @skipLoop
  728.     @loopBase:
  729.             move.l            (srcPixelP)+, (dstPixelP)+
  730.             move.l            (srcPixelP)+, (dstPixelP)+
  731.             move.l            (srcPixelP)+, (dstPixelP)+
  732.             move.l            (srcPixelP)+, (dstPixelP)+
  733.             move.l            (srcPixelP)+, (dstPixelP)+
  734.             move.l            (srcPixelP)+, (dstPixelP)+
  735.             move.l            (srcPixelP)+, (dstPixelP)+
  736.             move.l            (srcPixelP)+, (dstPixelP)+
  737.             move.l            (srcPixelP)+, (dstPixelP)+
  738.             move.l            (srcPixelP)+, (dstPixelP)+
  739.             move.l            (srcPixelP)+, (dstPixelP)+
  740.             move.l            (srcPixelP)+, (dstPixelP)+
  741.             move.l            (srcPixelP)+, (dstPixelP)+
  742.             move.l            (srcPixelP)+, (dstPixelP)+
  743.             move.l            (srcPixelP)+, (dstPixelP)+
  744.             move.l            (srcPixelP)+, (dstPixelP)+
  745.                 // decrement the loopsPerRow counter and loop back
  746.             subq.l            #1, d0
  747.             bne                @loopBase
  748. @skipLoop:
  749.                 // bump the source and dest pointers
  750.             adda.l            srcRowStride, srcPixelP
  751.             adda.l            dstRowStride, dstPixelP
  752.  
  753.                 // decrement the row counter and loop back
  754.             subq                #1, rowsToCopy
  755.             bne                @forEachRow
  756.  
  757. #if __MWERKS__
  758.             movem.l            (sp)+, loopsPerRow/rowsToCopy/pixelChunksPerRow/srcRowStride/dstRowStride/srcPixelP/dstPixelP
  759. #endif
  760.  
  761.             SW_ASM_END
  762. }
  763.  
  764.  
  765. ///--------------------------------------------------------------------------------------
  766. //        BlitPixieMask
  767. ///--------------------------------------------------------------------------------------
  768.  
  769. SW_ASM_FUNC void BlitPixieMask(
  770.     register PixelPtr srcPixelP,
  771.     register PixelPtr dstPixelP,
  772.     register PixelPtr maskPixelP,
  773.     register unsigned long rowsToCopy,
  774.     register unsigned long numBytesPerRow,
  775.     register unsigned long srcRowStride,
  776.     register unsigned long dstRowStride)
  777. {
  778.     register unsigned long loopsPerRow;
  779.  
  780.         SW_ASM_BEGIN
  781.  
  782. #if __MWERKS__
  783.         movem.l    loopsPerRow/srcPixelP/dstPixelP/maskPixelP/rowsToCopy/numBytesPerRow/srcRowStride/dstRowStride, -(sp)
  784.  
  785.         movea.l    36(sp), srcPixelP
  786.         movea.l    40(sp), dstPixelP
  787.         movea.l    44(sp), maskPixelP
  788.         move.l    48(sp), rowsToCopy
  789.         move.l    52(sp), numBytesPerRow
  790.         move.l    56(sp), srcRowStride
  791.         move.l    60(sp), dstRowStride
  792. #endif
  793.  
  794.             // longWordsPerRow = numBytesPerRow >> 2;
  795.         move.l    numBytesPerRow, d0
  796.         lsr.l        #2, d0
  797.  
  798.             // numBytesPerRow -= longWordsPerRow << 2;
  799.         move.l    d0, d1
  800.         lsl.l        #2, d1
  801.         sub.l        d1, numBytesPerRow
  802.  
  803.             // loopsPerRow = longWordsPerRow >> 4;
  804.         move.l    d0, loopsPerRow
  805.         lsr.l        #4, loopsPerRow
  806.  
  807.             
  808.         moveq        #0xF, d1
  809.         and.l        d1, d0
  810.         lsl.l        #3, d0                    // longWordsPerRow *= 8;
  811.         lea         @loopEnd, a0            // get address of the end of the loop
  812.         sub.l        d0, a0                    // calculate where to jmp in the loop
  813.  
  814.     @forEachRow:
  815.         move.l    loopsPerRow, d2
  816.         jmp        (a0)
  817.     @loopBase:
  818.             // 16
  819.         move.l    (dstPixelP), d0
  820.         and.l        (maskPixelP)+, d0
  821.         or.l        (srcPixelP)+, d0
  822.         move.l    d0, (dstPixelP)+
  823.             // 15
  824.         move.l    (dstPixelP), d0
  825.         and.l        (maskPixelP)+, d0
  826.         or.l        (srcPixelP)+, d0
  827.         move.l    d0, (dstPixelP)+
  828.             // 14
  829.         move.l    (dstPixelP), d0
  830.         and.l        (maskPixelP)+, d0
  831.         or.l        (srcPixelP)+, d0
  832.         move.l    d0, (dstPixelP)+
  833.           // 13
  834.         move.l    (dstPixelP), d0
  835.         and.l        (maskPixelP)+, d0
  836.         or.l        (srcPixelP)+, d0
  837.         move.l    d0, (dstPixelP)+
  838.           // 12
  839.         move.l    (dstPixelP), d0
  840.         and.l        (maskPixelP)+, d0
  841.         or.l        (srcPixelP)+, d0
  842.         move.l    d0, (dstPixelP)+
  843.           // 11
  844.         move.l    (dstPixelP), d0
  845.         and.l        (maskPixelP)+, d0
  846.         or.l        (srcPixelP)+, d0
  847.         move.l    d0, (dstPixelP)+
  848.           // 10
  849.         move.l    (dstPixelP), d0
  850.         and.l        (maskPixelP)+, d0
  851.         or.l        (srcPixelP)+, d0
  852.         move.l    d0, (dstPixelP)+
  853.           //  9
  854.         move.l    (dstPixelP), d0
  855.         and.l        (maskPixelP)+, d0
  856.         or.l        (srcPixelP)+, d0
  857.         move.l    d0, (dstPixelP)+
  858.           //  8
  859.         move.l    (dstPixelP), d0
  860.         and.l        (maskPixelP)+, d0
  861.         or.l        (srcPixelP)+, d0
  862.         move.l    d0, (dstPixelP)+
  863.           //  7
  864.         move.l    (dstPixelP), d0
  865.         and.l        (maskPixelP)+, d0
  866.         or.l        (srcPixelP)+, d0
  867.         move.l    d0, (dstPixelP)+
  868.             //  6
  869.         move.l    (dstPixelP), d0
  870.         and.l        (maskPixelP)+, d0
  871.         or.l        (srcPixelP)+, d0
  872.         move.l    d0, (dstPixelP)+
  873.           //  5
  874.         move.l    (dstPixelP), d0
  875.         and.l        (maskPixelP)+, d0
  876.         or.l        (srcPixelP)+, d0
  877.         move.l    d0, (dstPixelP)+
  878.           //  4
  879.         move.l    (dstPixelP), d0
  880.         and.l        (maskPixelP)+, d0
  881.         or.l        (srcPixelP)+, d0
  882.         move.l    d0, (dstPixelP)+
  883.           //  3
  884.         move.l    (dstPixelP), d0
  885.         and.l        (maskPixelP)+, d0
  886.         or.l        (srcPixelP)+, d0
  887.         move.l    d0, (dstPixelP)+
  888.             //  2
  889.         move.l    (dstPixelP), d0
  890.         and.l        (maskPixelP)+, d0
  891.         or.l        (srcPixelP)+, d0
  892.         move.l    d0, (dstPixelP)+
  893.           //  1
  894.         move.l    (dstPixelP), d0
  895.         and.l        (maskPixelP)+, d0
  896.         or.l        (srcPixelP)+, d0
  897.         move.l    d0, (dstPixelP)+
  898.     @loopEnd:
  899.         subq.l    #1, d2
  900.         bpl        @loopBase
  901.  
  902.         // now do any leftover bits
  903.         move.l    numBytesPerRow, d2
  904.         beq        @nextRow
  905.         subq.l    #2, d2
  906.         bmi        @moveByte
  907.         move.w    (dstPixelP), d0
  908.         and.w        (maskPixelP)+, d0
  909.         or.w        (srcPixelP)+, d0
  910.         move.w    d0, (dstPixelP)+
  911.         tst        d2
  912.         beq        @nextRow
  913.     @moveByte:    
  914.         move.b    (dstPixelP), d0
  915.         and.b        (maskPixelP)+, d0
  916.         or.b        (srcPixelP)+, d0
  917.         move.b    d0, (dstPixelP)+
  918.  
  919.     @nextRow:
  920.         adda.l    srcRowStride, srcPixelP
  921.         adda.l    srcRowStride, maskPixelP
  922.         adda.l    dstRowStride, dstPixelP
  923.         subq.l    #1, rowsToCopy
  924.         bne        @forEachRow
  925.  
  926. #if __MWERKS__
  927.         movem.l    (sp)+, loopsPerRow/srcPixelP/dstPixelP/maskPixelP/rowsToCopy/numBytesPerRow/srcRowStride/dstRowStride
  928. #endif
  929.  
  930.         SW_ASM_END
  931. }
  932.  
  933.  
  934. #endif /* SW_USE_C */
  935.